Merge "Deprecate static User::edits() in favour of User::getEditCount()"
authorSiebrand <siebrand@wikimedia.org>
Thu, 18 Oct 2012 00:00:11 +0000 (00:00 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 18 Oct 2012 00:00:11 +0000 (00:00 +0000)
1  2 
includes/Linker.php
includes/User.php

diff --combined includes/Linker.php
@@@ -448,7 -448,6 +448,7 @@@ class Linker 
         * @param $context IContextSource context to use to get the messages
         * @param $namespace int Namespace number
         * @param $title string Text of the title, without the namespace part
 +       * @return string
         */
        public static function getInvalidTitleDescription( IContextSource $context, $namespace, $title ) {
                global $wgContLang;
                if ( !$thumb ) {
                        $s = self::makeBrokenImageLinkObj( $title, $fp['title'], '', '', '', $time == true );
                } else {
 +                      self::processResponsiveImages( $file, $thumb, $hp );
                        $params = array(
                                'alt' => $fp['alt'],
                                'title' => $fp['title'],
                        $hp['width'] = isset( $fp['upright'] ) ? 130 : 180;
                }
                $thumb = false;
 +              $noscale = false;
  
                if ( !$exists ) {
                        $outerWidth = $hp['width'] + 2;
                        } elseif ( isset( $fp['framed'] ) ) {
                                // Use image dimensions, don't scale
                                $thumb = $file->getUnscaledThumb( $hp );
 +                              $noscale = true;
                        } else {
                                # Do not present an image bigger than the source, for bitmap-style images
                                # This is a hack to maintain compatibility with arbitrary pre-1.10 behaviour
                        $s .= wfMessage( 'thumbnail_error', '' )->escaped();
                        $zoomIcon = '';
                } else {
 +                      if ( !$noscale ) {
 +                              self::processResponsiveImages( $file, $thumb, $hp );
 +                      }
                        $params = array(
                                'alt' => $fp['alt'],
                                'title' => $fp['title'],
                return str_replace( "\n", ' ', $s );
        }
  
 +      /**
 +       * Process responsive images: add 1.5x and 2x subimages to the thumbnail, where
 +       * applicable.
 +       *
 +       * @param File $file
 +       * @param MediaOutput $thumb
 +       * @param array $hp image parameters
 +       */
 +      protected static function processResponsiveImages( $file, $thumb, $hp ) {
 +              global $wgResponsiveImages;
 +              if ( $wgResponsiveImages ) {
 +                      $hp15 = $hp;
 +                      $hp15['width'] = round( $hp['width'] * 1.5 );
 +                      $hp20 = $hp;
 +                      $hp20['width'] = $hp['width'] * 2;
 +                      if ( isset( $hp['height'] ) ) {
 +                              $hp15['height'] = round( $hp['height'] * 1.5 );
 +                              $hp20['height'] = $hp['height'] * 2;
 +                      }
 +
 +                      $thumb15 = $file->transform( $hp15 );
 +                      $thumb20 = $file->transform( $hp20 );
 +                      if ( $thumb15->url !== $thumb->url ) {
 +                              $thumb->responsiveUrls['1.5'] = $thumb15->url;
 +                      }
 +                      if ( $thumb20->url !== $thumb->url ) {
 +                              $thumb->responsiveUrls['2'] = $thumb20->url;
 +                      }
 +              }
 +      }
 +
        /**
         * Make a "broken" link to an image
         *
                        // check if the user has an edit
                        $attribs = array();
                        if ( $redContribsWhenNoEdits ) {
-                               $count = !is_null( $edits ) ? $edits : User::edits( $userId );
-                               if ( $count == 0 ) {
+                               if ( intval( $edits ) === 0 && $edits !== 0 ) {
+                                       $user = User::newFromId( $userId );
+                                       $edits = $user->getEditCount();
+                               }
+                               if ( $edits === 0 ) {
                                        $attribs['class'] = 'new';
                                }
                        }
diff --combined includes/User.php
@@@ -765,7 -765,6 +765,7 @@@ class User 
         *                - 'usable'     Valid for batch processes and login
         *                - 'creatable'  Valid for batch processes, login and account creation
         *
 +       * @throws MWException
         * @return bool|string
         */
        public static function getCanonicalName( $name, $validate = 'valid' ) {
  
        /**
         * Count the number of edits of a user
-        * @todo It should not be static and some day should be merged as proper member function / deprecated -- domas
         *
         * @param $uid Int User ID to check
         * @return Int the user's edit count
+        *
+        * @deprecated since 1.21 in favour of User::getEditCount
         */
        public static function edits( $uid ) {
-               wfProfileIn( __METHOD__ );
-               $dbr = wfGetDB( DB_SLAVE );
-               // check if the user_editcount field has been initialized
-               $field = $dbr->selectField(
-                       'user', 'user_editcount',
-                       array( 'user_id' => $uid ),
-                       __METHOD__
-               );
-               if( $field === null ) { // it has not been initialized. do so.
-                       $dbw = wfGetDB( DB_MASTER );
-                       $count = $dbr->selectField(
-                               'revision', 'count(*)',
-                               array( 'rev_user' => $uid ),
-                               __METHOD__
-                       );
-                       $dbw->update(
-                               'user',
-                               array( 'user_editcount' => $count ),
-                               array( 'user_id' => $uid ),
-                               __METHOD__
-                       );
-               } else {
-                       $count = $field;
-               }
-               wfProfileOut( __METHOD__ );
-               return $count;
+               wfDeprecated( __METHOD__, '1.21' );
+               $user = self::newFromId( $uid );
+               return $user->getEditCount();
        }
  
        /**
                if( $loggedOut !== null ) {
                        $this->mTouched = wfTimestamp( TS_MW, $loggedOut );
                } else {
 -                      $this->mTouched = '0'; # Allow any pages to be cached
 +                      $this->mTouched = '1'; # Allow any pages to be cached
                }
  
                $this->mToken = null; // Don't run cryptographic functions till we need a token
                $this->mEffectiveGroups = null;
                $this->mImplicitGroups = null;
                $this->mOptions = null;
 +              $this->mEditCount = null;
  
                if ( $reloadFrom ) {
                        $this->mLoadedItems = array();
  
                $defOpt = $wgDefaultUserOptions;
                # default language setting
 -              $variant = $wgContLang->getDefaultVariant();
 -              $defOpt['variant'] = $variant;
 -              $defOpt['language'] = $variant;
 +              $defOpt['variant'] = $wgContLang->getCode();
 +              $defOpt['language'] = $wgContLang->getCode();
                foreach( SearchEngine::searchableNamespaces() as $nsnum => $nsname ) {
                        $defOpt['searchNs'.$nsnum] = !empty( $wgNamespacesToBeSearchedDefault[$nsnum] );
                }
                if( $this->getId() ) {
                        if ( !isset( $this->mEditCount ) ) {
                                /* Populate the count, if it has not been populated yet */
-                               $this->mEditCount = User::edits( $this->mId );
+                               wfProfileIn( __METHOD__ );
+                               $dbr = wfGetDB( DB_SLAVE );
+                               // check if the user_editcount field has been initialized
+                               $count = $dbr->selectField(
+                                       'user', 'user_editcount',
+                                       array( 'user_id' => $this->mId ),
+                                       __METHOD__
+                               );
+                               if( $count === null ) {
+                                       // it has not been initialized. do so.
+                                       $dbw = wfGetDB( DB_MASTER );
+                                       $count = $dbr->selectField(
+                                               'revision', 'count(*)',
+                                               array( 'rev_user' => $this->mId ),
+                                               __METHOD__
+                                       );
+                                       $dbw->update(
+                                               'user',
+                                               array( 'user_editcount' => $count ),
+                                               array( 'user_id' => $this->mId ),
+                                               __METHOD__
+                                       );
+                               }
+                               wfProfileOut( __METHOD__ );
+                               $this->mEditCount = $count;
                        }
                        return $this->mEditCount;
                } else {
        }
  
        /**
 -       * Add this existing user object to the database
 +       * Add this existing user object to the database. If the user already 
 +       * exists, a fatal status object is returned, and the user object is 
 +       * initialised with the data from the database.
 +       *
 +       * Previously, this function generated a DB error due to a key conflict
 +       * if the user already existed. Many extension callers use this function
 +       * in code along the lines of:
 +       *
 +       *   $user = User::newFromName( $name );
 +       *   if ( !$user->isLoggedIn() ) {
 +       *       $user->addToDatabase();
 +       *   }
 +       *   // do something with $user...
 +       *
 +       * However, this was vulnerable to a race condition (bug 16020). By 
 +       * initialising the user object if the user exists, we aim to support this
 +       * calling sequence as far as possible.
 +       *
 +       * Note that if the user exists, this function will acquire a write lock,
 +       * so it is still advisable to make the call conditional on isLoggedIn(), 
 +       * and to commit the transaction after calling.
 +       *
 +       * @return Status
         */
        public function addToDatabase() {
                $this->load();
                                'user_registration' => $dbw->timestamp( $this->mRegistration ),
                                'user_editcount' => 0,
                                'user_touched' => $dbw->timestamp( $this->mTouched ),
 -                      ), __METHOD__
 +                      ), __METHOD__,
 +                      array( 'IGNORE' )
                );
 +              if ( !$dbw->affectedRows() ) {
 +                      $this->mId = $dbw->selectField( 'user', 'user_id', 
 +                              array( 'user_name' => $this->mName ), __METHOD__ );
 +                      $loaded = false;
 +                      if ( $this->mId ) {
 +                              if ( $this->loadFromDatabase() ) {
 +                                      $loaded = true;
 +                              }
 +                      }
 +                      if ( !$loaded ) {
 +                              throw new MWException( __METHOD__. ": hit a key conflict attempting " .
 +                                      "to insert a user row, but then it doesn't exist when we select it!" );
 +                      }
 +                      return Status::newFatal( 'userexists' );
 +              }
                $this->mId = $dbw->insertId();
  
                // Clear instance cache other than user table data, which is already accurate
                $this->clearInstanceCache();
  
                $this->saveOptions();
 +              return Status::newGood();
        }
  
        /**
        public static function getGroupsWithPermission( $role ) {
                global $wgGroupPermissions;
                $allowedGroups = array();
 -              foreach ( $wgGroupPermissions as $group => $rights ) {
 -                      if ( isset( $rights[$role] ) && $rights[$role] ) {
 +              foreach ( array_keys( $wgGroupPermissions ) as $group ) {
 +                      if ( self::groupHasPermission( $group, $role ) ) {
                                $allowedGroups[] = $group;
                        }
                }
                return $allowedGroups;
        }
  
 +      /**
 +       * Check, if the given group has the given permission
 +       *
 +       * @param $group String Group to check
 +       * @param $role String Role to check
 +       * @return bool
 +       */
 +      public static function groupHasPermission( $group, $role ) {
 +              global $wgGroupPermissions, $wgRevokePermissions;
 +              return isset( $wgGroupPermissions[$group][$role] ) && $wgGroupPermissions[$group][$role]
 +                      && !( isset( $wgRevokePermissions[$group][$role] ) && $wgRevokePermissions[$group][$role] );
 +      }
 +
        /**
         * Get the localized descriptive name for a group, if it exists
         *
         * @todo document
         */
        protected function loadOptions() {
 +              global $wgContLang;
 +
                $this->load();
 -              if ( $this->mOptionsLoaded || !$this->getId() )
 +
 +              if ( $this->mOptionsLoaded ) {
                        return;
 +              }
  
                $this->mOptions = self::getDefaultOptions();
  
 +              if ( !$this->getId() ) {
 +                      // For unlogged-in users, load language/variant options from request.
 +                      // There's no need to do it for logged-in users: they can set preferences,
 +                      // and handling of page content is done by $pageLang->getPreferredVariant() and such,
 +                      // so don't override user's choice (especially when the user chooses site default).
 +                      $variant = $wgContLang->getDefaultVariant();
 +                      $this->mOptions['variant'] = $variant;
 +                      $this->mOptions['language'] = $variant;
 +                      $this->mOptionsLoaded = true;
 +                      return;
 +              }
 +
                // Maybe load from the object
                if ( !is_null( $this->mOptionOverrides ) ) {
                        wfDebug( "User: loading options for user " . $this->getId() . " from override cache.\n" );